package edu.cmu.ece.ds.droidchat;

import java.util.ArrayList;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import edu.cmu.ece.ds.droidchat.NetworkService.LocalBinder;
import edu.cmu.ece.ds.droidchat.controller.ChatSessionMessageBaseAdapter;
import edu.cmu.ece.ds.droidchat.model.ChatMessage;
import edu.cmu.ece.ds.droidchat.model.StringConstants;
import edu.cmu.ece.ds.droidchat.model.UserInfo;

public class ChatWindowActivity extends Activity implements TextWatcher {
	private final String TAG = "ChatWindowActivity";
	
	private final static int ARRAY_SIZE = 100;
    private final static int DIVIDER_HEIGHT = 4;

    private ArrayList<ChatMessage> messageArray;
    private ChatSessionMessageBaseAdapter messageAdapter;
    private EditText mMessageToSend;
    private Button sendButton;

    // debug only
    private RadioButton self;
    private RadioButton other;
    private UserInfo aUser;

    private NetworkService mService;
    private boolean mBound = false;
    
    private String inviteeUsername;
    private boolean getPubKeySent = false;
    
    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub

    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // TODO Auto-generated method stub
        if (mMessageToSend.getText().length() == 0) {
            sendButton.setEnabled(false);
        } else {
            sendButton.setEnabled(true);
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Log.d(TAG, "---onCreate---");
        
        Intent i = getIntent();
        String username = i.getStringExtra("username");
        
        inviteeUsername = i.getStringExtra("username");
        
        if(mBound){
        	Log.d(TAG, "calling getUserPubKey() from NetworkService" + inviteeUsername);
        	
        	// sessionCreationHashtable is list of pending chat sessions
        	String newChatSessionID = Toolbox.addNewOneOnOneChatSessionInfoByUsername(username, mService.getLoginAttribute());
        	System.out.println(" newChatSessionID " + newChatSessionID);
        	
        	mService.getUserPubKey(username, newChatSessionID);
        } else {
        	Log.d(TAG, "want to call getUserPubKey() from NetworkService, but not bound to Service yet..." + inviteeUsername);
        }
        
        messageArray = new ArrayList<ChatMessage>(ARRAY_SIZE);
        this.setContentView(R.layout.chat_window_layout);

        // list view
        final ListView lv = (ListView) this
                .findViewById(R.id.chat_message_list_view);
        messageAdapter = new ChatSessionMessageBaseAdapter(this, messageArray);
        lv.setAdapter(messageAdapter);
        lv.setTextFilterEnabled(true);
        lv.setDivider(null);
        lv.setDividerHeight(DIVIDER_HEIGHT);
        // scroll to bottom when a new message arrives
        lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);

        // radio group, debug only
        self = (RadioButton) findViewById(R.id.radio_self);
        self.setChecked(true);
        other = (RadioButton) findViewById(R.id.radio_other);
        if (this.getIntent().getSerializableExtra(
                StringConstants.EXTRA_ANOTHER_USER_USER_NAME) != null) {
            aUser = Toolbox.retrieveUserInfo(this.getIntent().getStringExtra(
                    StringConstants.EXTRA_ANOTHER_USER_USER_NAME));
        } else {
            aUser = new UserInfo("46709394", "alpha", this.getResources()
                    .getDrawable(R.drawable.icon));
        }
        self.setText(Toolbox.getMyInfo().getNickName());
        other.setText(aUser.getNickName());

        // MessageSendingBarView
        mMessageToSend = (EditText) findViewById(R.id.message_input_field);
        mMessageToSend.addTextChangedListener(this);
        sendButton = (Button) findViewById(R.id.message_send_button);
        sendButton.setEnabled(false);
        sendButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (self.isChecked()) {
                    messageArray.add(new ChatMessage(Toolbox.getMyInfo(),
                            mMessageToSend.getText().toString()));
                    messageAdapter.notifyDataSetChanged();
                } else {
                    messageArray.add(new ChatMessage(aUser, mMessageToSend
                            .getText().toString()));
                    messageAdapter.notifyDataSetChanged();
                }
            }
        });

    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "---onStart---");

        // we probably need to also bind to NetworkService here for this Activity
        
        Intent intent = new Intent(this, NetworkService.class);
        Log.d(TAG, "calling bindService()");
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
    
    public void onPause() {
        super.onStop();
        Log.d(TAG, "---onPause---");
    }
    
    public void onStop() {
        super.onStop();
        Log.d(TAG, "---onStop---");
        Log.d(TAG, "---calling unbindService---");
        
        // we probably need to also unbind to NetworkService here for this Activity
        unbindService(mConnection);
        
        // whenever the BACK key is pressed, we kill the ChatWindowActivity
        finish();
    }
    
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "---onDestroy---");
    }
    
    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // We've bound to TCPService, cast the IBinder and get TCPService
            // instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            Log.d(TAG, mService.getPackageName());
            mBound = true;
            Log.d(TAG, "We've bound to TCPService");
            
            if(getPubKeySent==false){
            	Log.d(TAG, "calling getUserPubKey() from NetworkService: " + inviteeUsername);
            	
            	// sessionCreationHashtable is list of pending chat sessions
            	String newChatSessionID = Toolbox.addNewOneOnOneChatSessionInfoByUsername(inviteeUsername, mService.getLoginAttribute());
            	mService.getUserPubKey(inviteeUsername, newChatSessionID);
            	getPubKeySent = true;
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBound = false;
        }
    };
}
